package adapters;

import logic.Good;
import util.HibernateUtil;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import util.Preconditions;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Волков Олег on 19.06.14.
 * Базовый адаптер. Является родителем для всех остальных адаптеров. Обобщенная реализация методов, обязательных для всех Entity
 */
public class TableAdapter<T> {

    private static final Logger logger = Logger.getLogger(TableAdapter.class);

    private Class<T> klass;

    public TableAdapter(Class<T> klass) {
        this.klass = klass;
    }

    public void add(T object) {
        Preconditions.notNull(object);
        Session session = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            session.save(object);
            session.getTransaction().commit();
        } catch (Exception e) {
            logger.error("SQL problems: " + e.getMessage());
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
    }

    public void addAll(List<T> list) {
        Preconditions.notNull(list);
        for (T object:list){
            add(object);
        }
    }

    public void update (T object) {
        Preconditions.notNull(object);
        Session session = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            session.update(object);
            session.getTransaction().commit();
        } catch (Exception e) {
            logger.error("SQL problems: " + e.getMessage());
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
    }

    public void updateAll(List<T> list){
        Preconditions.notNull(list);
        for(T object:list){
            update(object);
        }
    }

    public Good getObjectById(int id) {
        Preconditions.notNull(id);
        Session session = null;
        Good good = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            good = (Good) session.load(Good.class, id);
        } catch (Exception e) {
            logger.error("SQL problems: " + e.getMessage());
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return good;
    }

    public List<T> getAll() {
        Session session = null;
        List<T> goods = new ArrayList<T>();
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            goods = session.createCriteria(klass).list();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return goods;
    }

    public void delete(T object) {
        Preconditions.notNull(object);
        Session session = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            session.delete(object);
            session.getTransaction().commit();
        } catch (Exception e) {
            logger.error("SQL problems: " + e.getMessage());
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
    }

    public void deleteAll(List<T> list) {
        Preconditions.notNull(list);
        for(T object:list){
            delete(object);
        }
    }

    // Кривой метод, разобраться, как писать параметризованный запрос, чтобы работало для произвольной таблицы
    public void deleteAll(){
        Session session = HibernateUtil.getSessionFactory().openSession();
        session.beginTransaction();
        String sqlQuery = "delete from Good";
        org.hibernate.Query query = session.createQuery(sqlQuery);
        query.setCacheable(true);
        query.executeUpdate();
        session.getTransaction().commit();

    }
}
